#ifndef PRIORITYQUEUECORE_H_INCLUDED
#define PRIORITYQUEUECORE_H_INCLUDED

namespace CEngine {

template<class E, class P>
PriorityQueue<E,P>::PriorityQueue(void)
    :   tree(),
        smallToBig(true)
{}

template<class E, class P>
PriorityQueue<E,P>::PriorityQueue(const E& element, const P& priority, const bool stb)
    :   tree(element, priority),
        smallToBig(stb)
{}

template<class E, class P>
PriorityQueue<E,P>::PriorityQueue(const PriorityQueue<E,P>& pQueue)
    :   tree(pQueue.tree),
        smallToBig(pQueue.smallToBig)
{}

template<class E, class P>
PriorityQueue<E,P>::PriorityQueue(const PriorityQueue& pQueue, const bool stb)
    :   tree(pQueue.tree),
        smallToBig(stb)
{}

template<class E, class P>
PriorityQueue<E,P>::PriorityQueue(const BinarySearchTree<E,P>& t, const bool stb)
    :   tree(t),
        smallToBig(stb)
{}

template<class E, class P>
PriorityQueue<E,P>::PriorityQueue(Vector<E>& vector, const P& priority, const bool stb)
    :   tree(vector, priority),
        smallToBig(stb)
{}

template<class E, class P>
PriorityQueue<E,P>&
PriorityQueue<E,P>::operator= (const PriorityQueue& pQueue) {
    if(this == &pQueue) {
        return *this;
    }

    tree = pQueue.tree;
    smallToBig = pQueue.smallToBig;

    return *this;
}

template<class E, class P>
PriorityQueue<E,P>&
PriorityQueue<E,P>::operator= (const BinarySearchTree<E,P>& t) {
    tree = t;

    return *this;
}

template<class E, class P>
PriorityQueue<E,P>&
PriorityQueue<E,P>::operator= (Vector<E>& vector) {
    tree = vector;

    return *this;
}

template<class E, class P>
PriorityQueue<E,P>::~PriorityQueue(void) {}

template<class E, class P>
E& PriorityQueue<E,P>::top(void) const {
    if(smallToBig) {
        return tree.min();
    }
    else {
        return tree.max();
    }
}

template<class E, class P>
void PriorityQueue<E,P>::push(const E& element) {
    tree.insert(element);
}

template<class E, class P>
void PriorityQueue<E,P>::push(const E& element, const P& priority) {
    tree.insert(element, priority);
}

template<class E, class P>
void PriorityQueue<E,P>::pop(void) {
    if(smallToBig) {
        tree.erase(tree.minKey);
    }
    else {
        tree.erase(tree.maxKey);
    }
}

template<class E, class P>
bool PriorityQueue<E,P>::isEmpty(void) const {
    return tree.isEmpty();
}

template<class E, class P>
U64 PriorityQueue<E,P>::getSize(void) const {
    return tree.getSize();
}

}

#endif // PRIORITYQUEUECORE_H_INCLUDED
